package com.video.demo.controller;



import com.video.demo.domain.Camera;
import com.video.demo.domain.CameraPojo;
import com.video.demo.domain.TaskEntity;
import com.video.demo.service.CameraService;
import com.video.demo.service.TaskHandler;
import com.video.demo.service.impl.TaskHandlerImpl;
import com.video.demo.util.CacheUtil;
import com.video.demo.util.HttpUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.web.servlet.server.Session;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 任务处理实现
 * @author lmc
 * @since jdk1.7
 * @version 2020-05-24
 */
@RestController
@RequestMapping("/video")
@CrossOrigin
public class VideoController{

    @Autowired
    private TaskHandlerImpl taskHandler;

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private CameraService cameraService;
    @Autowired
    private CameraController cameraController;
    private HashMap<Object, Object> VideoMap =new HashMap();
    @PostMapping("/live")
    public Map getComm4Map(StringBuffer rtsp,String videoName,Boolean a){
        StringBuffer comm1 = new StringBuffer();
        if (a!=null&&a){
            comm1= new StringBuffer("ffmpeg     -re -i  ");
        }else {
            comm1 =new StringBuffer("ffmpeg   -rtsp_transport  tcp  -re -i  ");
        }
        try {
            rtsp =comm1.append(rtsp);

            rtsp.append("  -tune zerolatency  -vcodec libx264  -profile Baseline -threads 2 -preset:v ultrafast  -b:v 400k -s 800x600 -r 15 -acodec libfaac  -an -f flv rtmp://218.29.12.71/myapp/").append(videoName);
//            rtsp.append("  -tune zerolatency  -vcodec libx264  -profile Baseline -threads 2 -preset:v ultrafast  -b:v 400k -s 800x600 -r 15 -acodec libfaac  -an -f flv rtmp://218.29.12.71:1936/").append(videoName);
//            ffmpeg   -rtsp_transport tcp  -re -i rtsp://admin:zjgt1234@218.29.12.71:7773/Streaming/Channels/101  -tune zerolatency  -vcodec libx264  -profile Baseline -threads 2 -preset:v ultrafast  -b:v 400k -s 800x600 -r 15 -acodec libfaac  -an -f flv rtmp://218.29.12.71/live/wei
//            ffmpeg   -rtsp_transport tcp  -re -i rtsp://admin:admin888888@192.168.55.11:554  -tune zerolatency  -vcodec libx264  -profile Baseline -threads 2 -preset:v ultrafast  -b:v 400k -s 800x600 -r 15 -acodec libfaac  -an -f flv rtmp://218.29.12.71/myapp/wei

            System.out.println(rtsp.toString());
            TaskEntity live2 = taskHandler.process(videoName, rtsp.toString());
            String rtmp ="http://218.29.12.71/myapp/"+videoName;
//            "http://218.29.12.71:6162/live?app=myapp&stream=47";
            HashMap<Object, Object> map = new HashMap<>();
            VideoMap.put(videoName,live2);
            map.put("rtmp",rtmp);
            return map;
        }catch (Exception e){
            return  null;
        }
    }
    @PostMapping("/stop")
    public String stop(String videoName){
        try {
            TaskEntity taskEntity = (TaskEntity) VideoMap.get(videoName);
            boolean stop = taskHandler.stop(taskEntity.getProcess());
            if (stop){
               stop = taskHandler.stop(taskEntity.getOutHandler());
            }
            if (stop){
                return "关闭了";
            }
            System.out.println("关闭了");
            return  "错误了";
        }catch(Exception e){
            return  "错误了";
        }
    }
    @PostMapping("/playback")
    public Map  playback(String playbackDate,String playbackEndDate,String videoName){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            //回放开始时间
            Date parse = sdf.parse(playbackDate);
            Calendar instance = Calendar.getInstance();
            instance.setTime(parse);

            int year = instance.get(Calendar.YEAR);//获取年份
            int month = instance.get(Calendar.MONTH);//获取月份
            int day = instance.get(Calendar.DATE);//获取日


            int hour = instance.get(Calendar.HOUR_OF_DAY);//时（24小时制）
            String minute = String.valueOf(instance.get(Calendar.MINUTE)+":"+instance.get(Calendar.SECOND));//分


            //回放截至时间
            Date parse2 = sdf.parse(playbackEndDate);
            Calendar instance2 = Calendar.getInstance();
            instance2.setTime(parse);

            int year2 = instance2.get(Calendar.YEAR);//获取年份
            int month2 = instance2.get(Calendar.MONTH);//获取月份
            int day2 = instance2.get(Calendar.DATE);//获取日

//          int hour = instance.get(Calendar.HOUR);//时（12小时制）
            int hour2 = instance2.get(Calendar.HOUR_OF_DAY);//时（24小时制）
            String minute2 = String.valueOf(instance.get(Calendar.MINUTE)+":"+instance.get(Calendar.SECOND));//分
//

            //拿到了一个视频的文件名
            String fileName = String.valueOf (hour)+"-"+String.valueOf ((hour+1))+".mp4";
            StringBuffer rtsp = new StringBuffer();
            rtsp.append(String.valueOf(year)+"/").append(String.valueOf(month)+"/")
                    .append(String.valueOf(day)+"/").append(String.valueOf(hour)+"/")
                    .append(fileName);
            Map getplayback = getplayback(rtsp, videoName, minute, minute2);
            return getplayback;
            /**
             *    /2020/7/13/11/11-12.mp4
             */
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public Map getplayback(StringBuffer rtsp,String videoName,String beginDate,String endDate){
        StringBuffer comm1 = new StringBuffer("ffmpeg   ");
        try {
            comm1.append("-ss"+beginDate);
            comm1.append("   -t"+endDate);
            comm1.append("-rtsp_transport tcp  -re -i  ");
            rtsp =comm1.append(rtsp);
            rtsp.append("  -tune zerolatency  -vcodec libx264  -profile Baseline -threads 2 -preset:v ultrafast  -b:v 400k -s 800x600 -r 15 -acodec libfaac  -an -f flv rtmp://218.29.12.71/myapp/").append(videoName);
//            ffmpeg   -rtsp_transport tcp  -re -i rtsp://admin:zjgt1234@218.29.12.71:7773/Streaming/Channels/101  -tune zerolatency  -vcodec libx264  -profile Baseline -threads 2 -preset:v ultrafast  -b:v 400k -s 800x600 -r 15 -acodec libfaac  -an -f flv rtmp://218.29.12.71/myapp/wei
            TaskEntity live2 = taskHandler.process(videoName, rtsp.toString());
            String rtmp ="http://218.29.12.71:6162/live?app=myapp&stream="+videoName;
//            "http://218.29.12.71:6162/live?app=myapp&stream=47";
            HashMap<Object, Object> map = new HashMap<>();
            VideoMap.put(videoName,live2);
            map.put("rtmp",rtmp);
            return map;
        }catch (Exception e){
            return  null;
        }
    }
    //stockpile  储存视频

    /**
     *
     * @param address
     * @param rtsp
     * @param projectId  实为 项目id
     */
    @PostMapping("/stockpile")
    public Map  stockpile(String address,StringBuffer rtsp,String projectId){
        Map getstockpile = getstockpile(rtsp, projectId, address);
        return getstockpile;
    }
    public Map getstockpile(StringBuffer rtsp,String videoName,String addressName){
        StringBuffer comm1 = new StringBuffer("ffmpeg   ");
        try {
            String  camera =cameraService.slect(videoName);
            comm1.append("-rtsp_transport tcp  -re -i  ");
            rtsp =comm1.append(rtsp);
            File file = new File("/usr/local/src/shipin" + camera);
            if(!file.exists() || file.length() == 0) {
                file.mkdirs();
            }
            rtsp.append("  -tune zerolatency  -vcodec libx264  -profile Baseline -threads 2 -preset:v ultrafast  -b:v 400k -s 800x600 -r 15 -acodec libfaac  -an -f flv /usr/local/src/shipin"+ camera);
            System.out.println(rtsp);
//            ffmpeg   -rtsp_transport tcp  -re -i rtsp://admin:zjgt1234@218.29.12.71:7773/Streaming/Channels/101  -tune zerolatency  -vcodec libx264  -profile Baseline -threads 2 -preset:v ultrafast  -b:v 400k -s 800x600 -r 15 -acodec libfaac  -an -f flv rtmp://218.29.12.71/myapp/wei
            TaskEntity live2 = taskHandler.process(videoName, rtsp.toString());
//            String rtmp ="http://218.29.12.71:6162/live?app=myapp&stream="+videoName;
//            "http://218.29.12.71:6162/live?app=myapp&stream=47";
            HashMap<Object, Object> map = new HashMap<>();
            VideoMap.put(videoName,live2);
//            map.put("rtmp",rtmp);
            map.put("videoName",videoName);
            return map;
        }catch (Exception e){
            return  null;
        }
    }
    public Map getstockpile2(StringBuffer rtsp,String videoName,String addressName){
        StringBuffer comm1 = new StringBuffer("ffmpeg   ");
        try {
//            String  camera =cameraService.slect(videoName);
            comm1.append("-rtsp_transport tcp  -re -i  ");
            rtsp =comm1.append(rtsp);
            File file = new File("/usr/local/src/shipin/" +addressName +"/"+ videoName);
            if(!file.exists() || file.length() == 0) {
                file.mkdirs();
            }
            rtsp.append("  -tune zerolatency  -vcodec libx264  -profile Baseline -threads 2 -preset:v ultrafast  -b:v 400k -s 800x600 -r 15 -acodec libfaac  -an -f flv /usr/local/src/shipin/"+addressName +"/"+ videoName);
            System.out.println(rtsp);
//            ffmpeg   -rtsp_transport tcp  -re -i rtsp://admin:zjgt1234@218.29.12.71:7773/Streaming/Channels/101  -tune zerolatency  -vcodec libx264  -profile Baseline -threads 2 -preset:v ultrafast  -b:v 400k -s 800x600 -r 15 -acodec libfaac  -an -f flv rtmp://218.29.12.71/myapp/wei
            TaskEntity live2 = taskHandler.process(videoName, rtsp.toString());
//            String rtmp ="http://218.29.12.71:6162/live?app=myapp&stream="+videoName;
//            "http://218.29.12.71:6162/live?app=myapp&stream=47";
            HashMap<Object, Object> map = new HashMap<>();
            VideoMap.put(videoName,live2);
//            map.put("rtmp",rtmp);
            map.put("videoName",videoName);
            return map;
        }catch (Exception e){
            return  null;
        }
    }
    /**
     * 萤石云拉流
     */
    @PostMapping( "/delete")
    @ResponseBody
    public void delete (String id,String deviceSerial)
    {
        redisTemplate.delete(deviceSerial);
    }
    /**
     * 萤石云拉流
     */
    @PostMapping( "/ysy")
    @ResponseBody
    public Map ysy (String id,String deviceSerial)
    {
        //判断是不是近期第一次接入设备，从萤石云拿流地址
        String rtmp =String .valueOf(redisTemplate.opsForHash().get(id, "rtmp"));
        String HLS =String .valueOf(redisTemplate.opsForHash().get(id, "HLS"));
        //判断之前近期有没有拉取过流，如果拉取过就直接用。
        String rtsp1 =String .valueOf(redisTemplate.opsForHash().get(deviceSerial, "rtsp"));
        String s1="200";
//        if(rtsp1!=""&&rtsp1!=null&&rtsp1!="null"){
//
////            HashMap<Object, Object> map = new HashMap<>();
////                map.put("rtmp",rtsp1);
////                //如果通了说明正在拉流，就直接返回前台拉流
////                return map;
//        try {
//
//            url = new URL(rtsp1);
//            String s = HttpUtils.get(url);
//
//            if (s=="200"&&s1=="200"){
//                HashMap<Object, Object> map = new HashMap<>();
//                map.put("rtmp",rtsp1);
//                //如果通了说明正在拉流，就直接返回前台拉流
//                return map;
//            }
//        } catch (MalformedURLException e) {
//            e.printStackTrace();
//        }
//        }
        //如果没有同说明没有拉流了，重新拉流
        StringBuffer rtsp=new StringBuffer();
        //判断rtmp是否存在，如果不存在就重新请求获取  s1=="200"代表 萤石云那边不需要重新拉流
        if (rtmp!=""&&rtmp!=null&&rtmp!="null"&&s1=="200") {
            URL url = null;
            try {
                url = new URL(HLS);
                s1 = HttpUtils.get(url);
                if (s1!="200"){
                    Map<String,String>   map = cameraService.ysy(id,deviceSerial);
                    rtmp = map.get("rtmpHd");
                    HLS = map.get("HLS");//http格式的，可以进行http请求判断是否通
                    rtsp= new StringBuffer(rtmp);//将萤石云的流地址获取
                    //重新赋值
                    redisTemplate.opsForHash().put(id,"rtmp",
                            rtmp);
                    redisTemplate.opsForHash().put(id,"HLS",
                            HLS);
                }
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
            rtsp= new StringBuffer(rtmp);//将萤石云的流地址获取
        }else {
         Map<String,String>   map = cameraService.ysy(id,deviceSerial);
            rtmp = map.get("rtmpHd");
            HLS = map.get("HLS");//http格式的，可以进行http请求判断是否通
            rtsp= new StringBuffer(rtmp);//将萤石云的流地址获取
            //重新赋值
            redisTemplate.opsForHash().put(id,"rtmp",
                    rtmp);
            redisTemplate.opsForHash().put(id,"HLS",
                    HLS);
        }
        //调用流媒体拉视频地址
        Map comm4Map = getComm4Map(rtsp, deviceSerial,true);
        //将流媒体拉过来的流，返回给前台，并且将流媒体的地址发送给前台
        String rtmp1 = String.valueOf(comm4Map.get("rtmp"));
//        rtmp1= http://218.29.12.71:6162/live?app=myapp&stream= "deviceSerial"
        redisTemplate.opsForHash().put(deviceSerial,"rtsp",
                rtmp1);
        return comm4Map;
    }
    /**
     * 萤石云拉流
     */
    @PostMapping( "/tunnelysy")
    @ResponseBody
    public Map tunnelysy (String id,String deviceSerial)
    {
        HashMap<Object, Object> map1 = new HashMap<>();
        CameraPojo cameraPojo1 = CacheUtil.STREAMMAP.get(deviceSerial);
        if (cameraPojo1!=null){
//            Object token = redisTemplate.opsForHash().get(id + deviceSerial, "token");
            map1.put("token", cameraPojo1.getToken());
            map1.put("url", cameraPojo1.getUrl());
            return map1;
        }
        //判断是不是近期第一次接入设备，从萤石云拿流地址
        String rtmp =String .valueOf(redisTemplate.opsForHash().get(id, "rtmp"));
        String HLS =String .valueOf(redisTemplate.opsForHash().get(id, "HLS"));
        String s1="200";
        //如果没有同说明没有拉流了，重新拉流
        StringBuffer rtsp=new StringBuffer();
        //判断rtmp是否存在，如果不存在就重新请求获取  s1=="200"代表 萤石云那边不需要重新拉流
        if (rtmp!=""&&rtmp!=null&&rtmp!="null"&&s1=="200") {
            URL url = null;
            try {
                url = new URL(HLS);
                s1 = HttpUtils.get(url);
                if (s1!="200"){
                    Map<String,String>   map = cameraService.tunnelysy(id,deviceSerial);
                    rtmp = map.get("rtmpHd");
                    HLS = map.get("HLS");//http格式的，可以进行http请求判断是否通
                    rtsp= new StringBuffer(rtmp);//将萤石云的流地址获取
                    //重新赋值
                    redisTemplate.opsForHash().put(id,"rtmp",
                            rtmp);
                    redisTemplate.opsForHash().put(id,"HLS",
                            HLS);
                }
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
            rtsp= new StringBuffer(rtmp);//将萤石云的流地址获取
        }else {
            Map<String,String>   map = cameraService.tunnelysy(id,deviceSerial);
            rtmp = map.get("rtmpHd");
            HLS = map.get("HLS");//http格式的，可以进行http请求判断是否通
            rtsp= new StringBuffer(rtmp);//将萤石云的流地址获取
            //重新赋值
            redisTemplate.opsForHash().put(id,"rtmp",
                    rtmp);
            redisTemplate.opsForHash().put(id,"HLS",
                    HLS);
        }
        CameraPojo cameraPojo = cameraController.openStream(rtmp, null, deviceSerial, null, null, null, null, null, null, null);
        //调用流媒体拉视频地址
        map1.put("token", cameraPojo.getToken());
        map1.put("url", cameraPojo.getUrl());
//        Map comm4Map = getComm4Map(rtsp, deviceSerial,true);
        //将流媒体拉过来的流，返回给前台，并且将流媒体的地址发送给前台
//        String rtmp1 = String.valueOf(comm4Map.get("rtmp"));
//        rtmp1= http://218.29.12.71:6162/live?app=myapp&stream= "deviceSerial"
        redisTemplate.opsForHash().put(deviceSerial,"rtsp",
                cameraPojo.getRtmp());
//        return comm4Map;
        return map1;
    }


    @PostMapping("/tunnellive")
    public Map tunnellive(StringBuffer rtsp,String videoName,Boolean a){
        StringBuffer comm1 = new StringBuffer();
        rtsp=new StringBuffer("C:\\Users\\Administrator\\Desktop\\"+rtsp);
        if (a!=null&&a){
            comm1= new StringBuffer("ffmpeg     -re -i  ");
        }else {
            comm1 =new StringBuffer("ffmpeg   -rtsp_transport  tcp  -re -i  ");
        }
        try {
            rtsp =comm1.append(rtsp);

            rtsp.append("  -tune zerolatency  -vcodec libx264  -profile Baseline -threads 2 -preset:v ultrafast  -b:v 400k -s 800x600 -r 15 -acodec libfaac  -an -f flv rtmp://127.0.0.1/live/").append(videoName);
//            rtsp.append("  -tune zerolatency  -vcodec libx264  -profile Baseline -threads 2 -preset:v ultrafast  -b:v 400k -s 800x600 -r 15 -acodec libfaac  -an -f flv rtmp://218.29.12.71:1936/").append(videoName);
//            ffmpeg   -rtsp_transport tcp  -re -i rtsp://admin:zjgt1234@218.29.12.71:7773/Streaming/Channels/101  -tune zerolatency  -vcodec libx264  -profile Baseline -threads 2 -preset:v ultrafast  -b:v 400k -s 800x600 -r 15 -acodec libfaac  -an -f flv rtmp://218.29.12.71/live/wei
//            ffmpeg   -rtsp_transport tcp  -re -i rtsp://admin:admin888888@192.168.55.11:554  -tune zerolatency  -vcodec libx264  -profile Baseline -threads 2 -preset:v ultrafast  -b:v 400k -s 800x600 -r 15 -acodec libfaac  -an -f flv rtmp://218.29.12.71/myapp/wei

            System.out.println(rtsp.toString());
            TaskEntity live2 = taskHandler.process(videoName, rtsp.toString());
//            http://192.168.55.32:8080/live?port=1935&app=live&stream=8101702e-23e2-4d9b-af00-de9c9b14850d
            String rtmp ="http://192.168.55.32:8080/live?port=1935&app=live&stream="+videoName;
//            "http://218.29.12.71:6162/live?app=myapp&stream=47";
            HashMap<Object, Object> map = new HashMap<>();
            VideoMap.put(videoName,live2);
            map.put("rtmp",rtmp);
            return map;
        }catch (Exception e){
            return  null;
        }
    }
}
